/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package msigraphx.handler;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.LineNumberReader;
import java.util.ArrayList;
import java.util.List;
import msigraphx.gibbsSampler.RandomVariableValue;
import msigraphx.graph.BayesianNetwork;
import msigraphx.graph.NetworkVertex;

/**
 *
 * @author adam
 */
public class NetworkReader {

    public String inFileName = new String();
    public String outFileName = new String();

    public BayesianNetwork readFile(String fileName) throws IOException {
        BayesianNetwork toReturn = new BayesianNetwork();
        if (fileName == null) {
            fileName = "input.txt";
        }
        inFileName = fileName;
        FileReader file = new FileReader(inFileName);
        LineNumberReader content = new LineNumberReader(file);
        String text;

        text = content.readLine();
        if (!text.matches("(\"[a-zA-Z0-9 ]+\", )+\"[a-zA-Z0-9 ]+\"")) {
            System.out.println("Niepoprawny format pliku1.");
            throw new IOException("Niepoprawny format wierzchołków w pliku wejściowym");
        }
        text = text.replaceAll("[\"]", "");
        String[] names = text.split(", ");

        int i = 0;
        ArrayList<NetworkVertex> vertexList = new ArrayList<NetworkVertex>();
        for (String name : names) {
            vertexList.add(new NetworkVertex(i++, name));
        }


        text = content.readLine();
        if (!text.matches("([0-9]+=[A-Za-z0-9]+, )+[0-9]+=[A-Za-z0-9]+")) {
            throw new IOException("Niepoprawny format wartosci dozwolonych w pliku wejsciowym " + content.getLineNumber());
        }

        String[] allowedValues = text.split(", ");
        for (String allowed : allowedValues) {
            String[] split = allowed.split("=");
            Integer index = Integer.parseInt(split[0]);
            vertexList.get(index).addAllowedValue(new RandomVariableValue<String>(vertexList.get(index), split[1]));
        }

        text = content.readLine();
        if (!text.matches("([0-9]+:[0-9]+, )+[0-9]+:[0-9]+")) {
            throw new IOException("Niepoprawny format relacji rodzic-dziecko w pliku wejsciowym " + content.getLineNumber());
        }

        String[] parentsChildren = text.split(", ");
        for (String parentChild : parentsChildren) {
            String[] split = parentChild.split(":");
            Integer parentIndex = Integer.parseInt(split[0]);
            Integer childIndex = Integer.parseInt(split[1]);

            vertexList.get(childIndex).addParent(vertexList.get(parentIndex));
        }

        while ((text = content.readLine()) != null) {
            if (!text.matches("[0-9]+\\([0-9]+\\), 0.[0-9]+f, (null|(([0-9]+\\([0-9]+\\), )+[0-9]+\\([0-9]+\\)))")
                    && !text.matches("[0-9]+\\([0-9]+\\), 0.[0-9]+f, [0-9]+\\([0-9]+\\)")) {
                throw new IOException("Niepoprawny format CondDistr w pliku wejsciowym " + content.getLineNumber());
            }
            String[] CondDistr = text.split(", ");
            int openBracket = CondDistr[0].indexOf("(");
            int closeBracket = CondDistr[0].indexOf(")");
            Integer vertexIndex = Integer.parseInt(CondDistr[0].substring(0, openBracket));
            Integer allowedValueIndex = Integer.parseInt(CondDistr[0].substring(openBracket + 1, closeBracket));
            RandomVariableValue<String> thisValue = vertexList.get(vertexIndex).getAllowedValue(allowedValueIndex);

            Float distr = Float.parseFloat(CondDistr[1]);

            List<RandomVariableValue<String> > randomVariableValues = new ArrayList<RandomVariableValue<String> >();
            for (int rest = 2; rest < CondDistr.length; rest++) {
                openBracket = CondDistr[rest].indexOf("(");
                closeBracket = CondDistr[rest].indexOf(")");
                if (openBracket > 0) {
                    vertexIndex = Integer.parseInt(CondDistr[rest].substring(0, openBracket));
                    allowedValueIndex = Integer.parseInt(CondDistr[rest].substring(openBracket + 1, closeBracket));

                    randomVariableValues.add(vertexList.get(vertexIndex).getAllowedValue(allowedValueIndex));
                }
            }
            vertexList.get(vertexIndex).distr.setDistrProb(thisValue, randomVariableValues, distr);

        }
        for (NetworkVertex in : vertexList) {
            toReturn.addVertex(in);
        }
        return toReturn;
    }
}
